﻿/*
 * Twipler - Twitter Web Client with features.
 *  
 *  Copyright (C) 2009, 2010. Ian Quigley
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details. 
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Twipler.App.Machine;
using Twipler.App.Machine.Instructions;
using Twipler.App.Parse.Code;
using Twipler.App.Parse.Html;
using Twipler.App.Render.Tree;
using UnitTests.App.Parse.Producer;
using Xunit;
using Xunit.Extensions;

namespace UnitTests.App.Parse
{
    public abstract class GivenProgram : ContextSpecification
    {
        private ArrangeCodeParser _testBuilder;
        private CodeParse _codeParse;
        private List<Instruction> _resultProgram;
        
        protected void Build(params Instruction[] program)
        {
            _testBuilder = new ArrangeCodeParser(program);
            _codeParse = new CodeParse(_testBuilder.Test);
            _resultProgram = _codeParse.ReadInstructions();
        }

        public override void Because()
        {
        }

        [Fact]
        protected void VerifyParseWithNoErrors()
        {
            Assert.Equal(_codeParse.Errors.Count, 0);
        }

        [Fact]
        protected void VerifySameProgramStructure()
        {
            _testBuilder.AssertSame(_resultProgram);
        }
    }

    public class GivenPop : GivenProgram
    {
        public override void  EstablishContext()
        {
            Build(new Pop());
        }
    }

    public class GivenPopPop : GivenProgram
    {
        public override void EstablishContext()
        {
            Build(new Pop(), new Pop());
        }
    }

    public class GivenDeclare : GivenProgram
    {
        public override void EstablishContext()
        {
            Build(new Declare(new Variable("Int32","XY")));
        }
    }

    public class GivenPushIPop : GivenProgram
    {
        public override void EstablishContext()
        {
            Build(new PushI(3), new Pop());
        }
    }

    public class GivenDeclarePopV : GivenProgram
    {
        public override void EstablishContext()
        {
            Build(new Declare(new Variable("Int32", "XYZ")), new PopV("XYZ"));
        }
    }

    public class GivenAddiMuliEqiGeiGt : GivenProgram
    {
        public override void EstablishContext()
        {
            Build(new AddI(), new MulI(), new EqI(), new GeI(), new GtI());
        }
    }

    public class GivenCall : GivenProgram
    {
        public override void EstablishContext()
        {
            Build(new Call(new StaticMethodCall() { MethodName = "Page.FromQueryStringInt", Params = new List<Variable>() { new Variable("Page"), new Variable(3) } }));
        }
    }
}
